#!/usr/bin/env python
import subprocess

class wsl_usb_port:
    def __init__(self):
        self.port_list = self.port_list_read(0)
        self.attach_port = self.get_attach_port()

    def get_attach_port(self):
        for tmp in self.port_list:
            if tmp['ATTACHE_STATE']:
                return tmp

        return None

    def port_list_fresh(self):
        self.port_list= self.port_list_read(0)
        self.attach_port = self.get_attach_port()

        self.port_list_put(self.port_list)

    def is_port_attach(self):
        return True if self.attach_port is not None else False

    def get_attach_bus_id(self, index=0):
        return self.attach_port['BUSID']

    def get_bus_id(self, index=0):
        return self.port_list[index]['BUSID']

    def get_attach_bus_id(self):
        return self.attach_port['BUSID']

    def port_reattach(self):
        if self.is_port_attach():
            bus_id = self.get_attach_bus_id()
            self.port_config(bus_id, 0)
            print('[LOG]Port Detach Successed')
            self.port_config(bus_id, 1)
            print('[LOG]Port Attach Successed')
        else:
            print('[ERROR]Port Is Not Attach')

    def run_console(self):
        self.port_list_fresh()

        desc_str  = '\nfunc_index:0, desc:get wsl usb port list'
        desc_str += '\nfunc_index:1, desc:attach wsl usb port'
        desc_str += '\nfunc_index:2, desc:detach wsl usb port'
        desc_str += '\nfunc_index:3, desc:reattach wsl usb port'
        desc_str += '\nset func index:'

        try:
            index = int(input(desc_str))

            if index == 1:
                port_bus_id = self.get_bus_id(int(input('set wsl2 attached port index:')))
                self.port_config(port_bus_id, 1)
                print('[LOG]Port Attach Successed')
            elif index == 2:
                if self.is_port_attach():
                    self.port_config(self.get_attach_bus_id(), 0)
                    print('[LOG]Port Detach Successed')
                else:
                    print('[ERROR]Port Is Not Attach')
            elif index == 3:
                self.port_reattach()
                print('[LOG]Port Reattach Successed')
            else:
                print('[ERROR]Not Support Param')

        except:
            print('Input Param \"func_index\" Error')

    @staticmethod
    def port_list_read(put_info=1):
        get_port_cmd = 'usbipd wsl list'

        process = subprocess.Popen(get_port_cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.STDOUT,
                                   encoding='utf-8')
        process.wait()

        cmd_output = str(process.stdout.read())

        out_str_list = cmd_output.split('\n')
        out_val_list = []

        for i in range(0, len(out_str_list)):
            line_data = []
            line_str = ''
            temp_str_list = out_str_list[i].split(' ')

            for j in range(0, len(temp_str_list)):
                if len(temp_str_list[j]):
                    if len(line_str):
                        line_str += ' '

                    line_str += temp_str_list[j]
                elif len(line_str):
                    line_data.append(line_str)
                    line_str = ''

            if len(line_str):
                line_data.append(line_str)

            if len(line_data):
                out_val_list.append(line_data)

        # out_val_list = out_val_list[1:]

        port_list = []

        for i in range(1, len(out_val_list)):
            port_dict = {}

            for j in range(0, len(out_val_list[i])):
                port_dict[out_val_list[0][j]] = out_val_list[i][j]
            port_dict['INDEX'] = i-1

            if port_dict['STATE'] == 'Not attached':
                port_dict['ATTACHE_STATE'] = 0
            else:
                port_dict['ATTACHE_STATE'] = 1

            port_list.append(port_dict)

        return port_list

    @staticmethod
    def port_list_put(port_list):
        print('\nPut WSL USB Port List:')
        for port_dict in port_list:
            val_str = 'index:{}, name:{}, bus_id:{}, state:{}'.format(port_dict['INDEX'],
                                                                      port_dict['DEVICE'],
                                                                      port_dict['BUSID'],
                                                                      port_dict['STATE'])
            print(val_str)

    @staticmethod
    def port_config(bus_id, set=1):
        attach_cmd = 'usbipd wsl attach --busid %s' % (str(bus_id))
        detach_cmd = 'usbipd wsl detach --busid %s' % (str(bus_id))

        if set:
            cmd = attach_cmd
        else:
            cmd = detach_cmd

        process = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.STDOUT,
                                   encoding='utf-8')
        process.wait()

        print(str(process.stdout.read()))

if __name__ == '__main__':
    port = wsl_usb_port()

    while True:
        port.run_console()

